/*
 * @Author: 郑子胜(Zechariahzheng)
 * @Date: 2023-09-18 11:32:07
 * @LastEditors: 郑子胜(Zechariahzheng)
 * @LastEditTime: 2024-01-10 17:15:34
 * @Descripttion: 
 */
#ifndef MY_MQTT_H__
#define MY_MQTT_H__
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Ticker.h>
#include <LittleFS.h>

#define DEBUG 1

#ifdef DEBUG
  #define MQTT_DEBUG_PRINT(x)  Serial.print (x)
  #define MQTT_DEBUG_PRINTLN(x) Serial.println (x)
#else
  #define MQTT_DEBUG_PRINT(x)
  #define MQTT_DEBUG_PRINTLN(x)
#endif

// 所有订阅主题
struct AllTopic {
  const char *pub_online_topic;
  const char *pub_cmd_topic;
  const char *pub_msg_topic;
  const char *sub_cmd_topic;
  const char *sub_msg_topic;
  const char *sub_bafa_topic;
  AllTopic(const char *a, const char *b, 
    const char *c, const char *d, 
    const char *e, const char *f): pub_online_topic(a), pub_cmd_topic(b), pub_msg_topic(c), sub_cmd_topic(d), sub_msg_topic(e), sub_bafa_topic(f){};
};

// MQTT信息
struct MQTTInfo {
  const char *mqtt_server;
  const uint16_t mqtt_server_port;
  const char *user;
  const char *pass;
  const char *sn;
  const uint8_t keepalive;
  MQTTInfo(const char *a, const uint16_t f, const char *b, 
    const char *c, const char *d, 
    const uint8_t e): mqtt_server(a), mqtt_server_port(f),  user(b), pass(c), sn(d), keepalive(e) {};
};

// 设备信息
class DeviceInfo {
public:
  // 通过json字符串设置信息
  virtual void setInfo(String payload) const = 0;
  // 获取信息
  virtual String getInfo() const = 0;
  // 做某事
  virtual void doSomething(const char *puhDepth, const char *lastTime) const {};
};


class MyMqtt {
  public:
    void init(WiFiClient *espClient, const MQTTInfo *mqttInfo, const AllTopic *allTopic, const DeviceInfo *deviceInfo);
    // 设置id
    void setMqttId(String id);
    // 运行中设置id
    void loopSetMqttId(String id);
    // 循环函数
    void loop();
    ~MyMqtt();

  private:
    WiFiClient *espClient;
    PubSubClient *client;
    const MQTTInfo *mqttInfo;
    const AllTopic *allTopic;
    Ticker ticker, mqttTicker;      // 定时对象
    boolean heart_flag;
    char ip[18];                    // ip地址
    char mqtt_id[35];               // mqtt连接id
    
    // 心跳消息
    void heartBeat();
    void reconnect();
    
    static void ticker_trigger(MyMqtt *objectPtr) {
      objectPtr->heartBeat();
    }
};


#endif